﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using AutoLoL.Entities;
using AutoLoL.Logic;
using AutoLoL.Logic.Exceptions;
using System.Collections.ObjectModel;

namespace AutoLoL.Logic.Automation
{
    public class AutoDeploy
    {
        public struct ItemSet:IComparable<ItemSet>
        {
            public int index;
            public string name;
            public List<int> items;

            public ItemSet(ItemSet set)
            {
                index = set.index;
                name = set.name;
                items = new List<int>(set.items);
            }

            public int CompareTo(ItemSet other)
            {
                return index.CompareTo(other.index);
            }
        }

        private static List<ItemSet> mItemSets = new List<ItemSet>();
        private static string mChampion = "";
        private static GameType mGameType = GameType.Classic;

        public static ReadOnlyCollection<ItemSet> getItemSets()
        {
            return mItemSets.AsReadOnly();
        }

        public static string getChampion()
        {
            return mChampion;
        }

        public static GameType getGameType()
        {
            return mGameType;
        }

        private static string getDeployDir(string champion)
        {
            //Get the directory the user set
            string dir = UserSettings.Instance.LolDirectory;

            //Add this hardcoded mess that should hopefully stay the same according to: http://na.leagueoflegends.com/board/showthread.php?t=1177803
            dir += "\\RADS\\solutions\\lol_game_client_sln\\releases\\";

            //Find the correct version number subdirectory just in case this changes in the future
            string[] dirs = Directory.GetDirectories(dir);
            if (dirs.Length > 1)
            {
                Version biggestVer = new Version(0, 0, 0, 0);
                int biggestVerIndex = 0;
                for (int i = 0; i < dirs.Length; i++)
                {
                    Version ver = new Version(dirs[i]);
                    if (ver > biggestVer)
                    {
                        biggestVer = ver;
                        biggestVerIndex = i;
                    }
                }

                dir += Path.GetFileName(dirs[biggestVerIndex]);
            }
            else if (dirs.Length < 1)
            {
                throw new ItemDirectoryNotFoundException();
            }
            else
            {
                dir += Path.GetFileName(dirs[0]);
            }

            //More hardcoded stuff
            dir += "\\deploy\\DATA\\";

            //Make sure the directory we are in exist so far
            if (!Directory.Exists(dir))
            {
                throw new ItemDirectoryNotFoundException();
            }

            //Create the nessisary subdirectories if they don't exist
            dir += "Characters\\" + champion;
            Directory.CreateDirectory(dir);

            return dir;
        }

        public static void addSet(string champion, GameType gameType, Item[] items, int setNumber = 1, string setName = "Main")
        {
            if ((mChampion != "" && mChampion != champion) || mGameType != gameType)
            {
                mItemSets.Clear();
            }

            mChampion = champion;
            mGameType = gameType;

            ItemSet itemSet;
            itemSet.items = new List<int>();

            if (mItemSets.Count > 0)
            {
                //Look for our same set
                int index = -1;
                for (int i = 0; i < mItemSets.Count; i++)
                {
                    if (mItemSets[i].name == setName)
                    {
                        index = i;
                        break;
                    }
                }

                //Set the values of the passed in itemset
                itemSet.name = setName;
                itemSet.index = setNumber;
                itemSet.items.Clear();
                for (int i = 0; i < items.Length; i++)
                {
                    itemSet.items.Add(items[i].ItemId);
                }

                //If found then remove it so it can be replaced
                if( index >= 0)
                {
                    mItemSets.RemoveAt(index);
                }

                //Organize the set
                mItemSets.Sort();

                //Update all the index values so no two are the same
                int lastSetNumber = setNumber;
                for (int i = 0; i < mItemSets.Count; i++)
                {
                    ItemSet set = mItemSets[i];
                    if (set.index == lastSetNumber)
                    {
                        set.index += 1;
                        lastSetNumber = set.index;
                    }
                }

                //Add the new item
                mItemSets.Add(itemSet);

                //Organize the set
                mItemSets.Sort();
            }
            else
            {
                //Add the new items
                itemSet.name = setName;
                itemSet.index = setNumber;
                for (int i = 0; i < items.Length; i++)
                {
                    itemSet.items.Add(items[i].ItemId);
                }
                mItemSets.Add(itemSet);
            }
        }

        public static bool readFromFile(string champion, GameType gameType = GameType.Classic)
        {
            //get the directory to write to
            string dir = getDeployDir(champion);

            //File name to write to
            dir += "\\RecItems";
            switch (gameType)
            {
                case GameType.Dominion: dir += "ODIN"; break;
                case GameType.ARAM: dir += "ARAM"; break;
                default: dir += "CLASSIC"; break;
            }

            dir += ".ini";

            if (File.Exists(dir))
            {
                //Read in the current sets and store them in our stucture
                string[] CurrentFile = File.ReadAllLines(dir);
                ItemSet temp = new ItemSet();
                temp.items = new List<int>();
                mItemSets.Clear();
                mChampion = champion;
                mGameType = gameType;
                for (int i = 0; i < CurrentFile.Length; i++)
                {
                    //get our item set number
                    if (CurrentFile[i].IndexOf("[ItemSet") >= 0)
                    {
                        //If we already filled up temp then add it to our list
                        if (temp.items.Count > 0)
                        {
                            mItemSets.Add(new ItemSet(temp));
                            temp.items.Clear();
                        }

                        string str = CurrentFile[i];
                        str = str.Replace("[ItemSet", "");
                        str = str.Replace("]", "");
                        temp.index = int.Parse(str);
                    }

                    //get our item set name
                    if (CurrentFile[i].IndexOf("SetName=") >= 0)
                    {
                        string str = CurrentFile[i];
                        str = str.Replace("SetName=", "");
                        temp.name = str;
                    }

                    //get all the items that make up the set
                    if (CurrentFile[i].IndexOf("RecItem") >= 0)
                    {
                        string str = CurrentFile[i];
                        int pos1, pos2;
                        pos1 = str.IndexOf("RecItem") + 7;
                        pos2 = str.IndexOf("=");
                        int itemNumber = int.Parse(str.Substring(pos1, pos2 - pos1));
                        int itemId = int.Parse(str.Substring(pos2+1));

                        temp.items.Insert(itemNumber - 1, itemId);
                    }
                }

                //If we already filled up temp then add it to our list
                if (temp.items.Count > 0)
                {
                    mItemSets.Add(new ItemSet(temp));
                    temp.items.Clear();
                }

                return true;
            }

            return false;
        }

        public static void Deploy()
        {
            //get the directory to write to
            string dir = getDeployDir(mChampion);

            //File name to write to
            dir += "\\RecItems";
            switch (mGameType)
            {
                case GameType.Dominion: dir += "ODIN"; break;
                case GameType.ARAM: dir += "ARAM"; break;
                default: dir += "CLASSIC"; break;
            }
            dir += ".ini";

            //Organize the set acording to the index before writing them out
            mItemSets.Sort();

            //Write the list out to a string so we can then write it to the file
            List<string> contents = new List<string>();
            for (int i = 0; i < mItemSets.Count; i++)
            {
                contents.Add("[ItemSet" + (i + 1) + "]");
                contents.Add("SetName=" + mItemSets[i].name);

                //Add all the items we set
                for (int j = 0; j < mItemSets[i].items.Count; j++)

                {
                    contents.Add("RecItem" + (j + 1) + "=" + mItemSets[i].items[j]);
                }

                //Add Space
                contents.Add("");
            }
            
            File.WriteAllLines(dir, contents.ToArray());
        }
    }
}
